#ifndef __MATCHROOM_H__
#define __MATCHROOM_H__
#include <vector>
#include <list>
#include <unordered_map>

#include "player.h"
#include "singleton.h"
#include "proto/message.pb.h"

class MatchRoom
{
public:
    typedef std::shared_ptr<MatchRoom> ptr;
    MatchRoom(int roomId);

    std::list<Player::ptr>& GetPlayers() { return m_players; }

    int GetRoomId();

    Player::ptr& GetBanker()
    {
        return m_banker;
    }

    void SetBanker(Player::ptr& player)
    {
        m_banker = player;
    }

    bool IsBanker(Player::ptr& player)
    {
        return player == m_banker;
    }

    proto::RoomType GetRoomType();

    void SetRoomType(proto::RoomType roomType);
    //房间是否已满
    bool IsFull();
    //是否全部玩家都已准备
    bool IsAllReady();
    //进入房间
    void Enter(Player::ptr& player);
    //离开房间
    void Leave(int playerId);
    //是否已准备
    bool IsReady(int playerId);
    //准备
    void Ready(int playerId);
    //取消准备
    void CancelReady(int playerId);
    //分配座位
    proto::SeatPosition DistributionSeat();
    //回收座位
    void RecycleSeat(proto::SeatPosition seatpostion);
    //广播消息
    void BroadCast(proto::NetMsg& netMsg, bool isContainSelf, Player::ptr& player);

    void PickBanker();

    void DealCard();

    void SortCard();

    void GetCardType();

    Player::ptr GetPlayer(proto::SeatPosition seatPosition);

    Player::ptr& GetNextPlayer(proto::SeatPosition seatPosition);

    void AddToGiveUp(int playerId);

    bool IsGiveUp(int playerId);

    void ClearRoom();

    bool operator==(Player::ptr& player);
private:
    int m_roomId;
    proto::RoomType m_roomType;
    Player::ptr m_banker;
    //房间中的所有玩家
    std::list<Player::ptr> m_players;
    //已经准备的玩家集合
    std::vector<int> m_alreadyPlayers;
    //已弃牌的玩家集合
    std::vector<int> m_giveUpCards;
    //房间中剩余的位置
    std::vector<proto::SeatPosition> m_remainSeats;
};

class RoomManager
{
public:
    static int roomIdSeed;
    //某个玩家进入某种类型的房间
    MatchRoom::ptr Enter(Player::ptr& player, proto::RoomType roomType);
    //玩家离开
    MatchRoom::ptr Leave(Player::ptr& player);
    //得到玩家所在的房间
    MatchRoom::ptr GetRoom(Player::ptr& player);
private:
    //玩家和房间的映射
    std::unordered_map<int, int> m_playerInRoom;
    //已满的房间号和房间的映射
    std::unordered_map<int, MatchRoom::ptr> m_FullRooms;
    //未满的房间号和房间的映射
    std::unordered_map<int, MatchRoom::ptr> m_UnFullRooms;
    //正在进行游戏的房间
    std::unordered_map<int, MatchRoom::ptr> m_PlayingRooms;
};

typedef Singleton<RoomManager> RoomMgr;

#endif // !__MATCHROOM_H__